package com.teamblueplus.comicmaker;

import java.util.ArrayList;

import com.teamblueplus.R;
import com.teamblueplus.brush.PaintBrush;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.View.MeasureSpec;
import android.widget.EditText;

/**
 * This class is the drawing thread of ComicMaking, thread is running in a loop
 * for drawing
 * 
 * @author qui
 * 
 */
class ComicDrawThread extends Thread {
	String TAG = "TestThread";
	private SurfaceHolder _surfaceHolder;
	private boolean _run = false;
	public volatile boolean isDrawing = true;
	Bitmap bubbleBitmap;
	Bitmap background;
	boolean drawImageBackground = false;
	ArrayList<DrawingLayer> layerArray;

	boolean touched; // check for touch input
	boolean isSaved = false;
	boolean isSelected;
	int selectedLayer;

	private Resources mRes;
	private Context mContext; // context of activity

	Paint rectPaint; // for highlight selected layer

	int selectedLayerX; // for moving layer
	int selectedLayerY; // for moving layer
	
	boolean sleep;

	// ########################################################
	// for brush functionality
	public PaintBrush brush2;
	public Bitmap mBitmap;

	// use for brush functionality
	// not useful for now
	private Handler previewDoneHandler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			Log.d("draw", "handleMessage is Drawing FALSE");
			// isDrawing = false;
		}
	};

	// ########################################################

	/**
	 * constructor for the drawing thread
	 * 
	 * @param surfaceHolder
	 * @param context
	 */
	public ComicDrawThread(SurfaceHolder surfaceHolder, Context context) {
		_surfaceHolder = surfaceHolder;
		mContext = context;
		mRes = context.getResources();

		layerArray = new ArrayList<DrawingLayer>();

		// create bubble and load bitmap
		bubbleBitmap = BitmapFactory.decodeResource(mRes,
				R.drawable.bubble_image);
		
		

		rectPaint = new Paint();
		rectPaint.setColor(Color.GREEN);
		rectPaint.setStrokeWidth(4);
		rectPaint.setStyle(Paint.Style.STROKE);

		// brush functionality
		// init brush
		brush2 = new PaintBrush();
		mBitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
		
		sleep = true;

	}

	public void setRunning(boolean run) {
		_run = run;
	}

	@Override
	public void run() {
		if (sleep) {
			try {
				Thread.sleep(900);
				sleep = false;
	        } catch (InterruptedException e) {
	            // TODO Auto-generated catch block
	            e.printStackTrace();
	        }
		}
		
		Canvas c;
		while (_run) {
			if (isDrawing) {
				c = null;
				try {
					if (_surfaceHolder == null) {
						Log.d("Surface Holder", "is null");
					}
					
					c = _surfaceHolder.lockCanvas();
					synchronized (_surfaceHolder) {
						onDraw(c);
					}
				} finally {
					// do this in a finally so that if an exception is thrown
					// during the above, we don't leave the Surface in an
					// inconsistent state
					if (c != null) {
						_surfaceHolder.unlockCanvasAndPost(c);
					}
				}
			}
		}
	}

	/**
	 * Main draw method
	 * 
	 * @param canvas
	 */
	public void onDraw(Canvas canvas) {
		int width = canvas.getWidth();
		int height = canvas.getHeight();

		// canvas.drawColor(Color.rgb(187, 255, 255));

		// #################################################################
		// drawing the brush

		// if(mBitmap == null){
		// Log.d("###", "initialize mBitmap");
		// mBitmap = Bitmap.createBitmap (1, 1, Bitmap.Config.ARGB_8888);
		// }

		// #################################################################
		// drawing the brush

		if (mBitmap == null) {
			Log.d("###", "initialize mBitmap");
			mBitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
		}

		// we created another canvas with bitmap as parameter so the canvas
		// will be draw into the bitmap, the bitmap will be use to save all
		// the drawings when we save it to a file.
		final Canvas c2 = new Canvas(mBitmap);

		// draw black background
		if(this.drawImageBackground)
			c2.drawBitmap(this.background, 0, 0,null);
		else
		    c2.drawColor(Color.rgb(187, 255, 255));

		// draw image layer
		for (int i = 0; i < layerArray.size(); i++) {
			DrawingLayer layer = layerArray.get(i);
			Bitmap layerBitmap = layer.getBitmap();
			int layerWidth = layer.getBitmap().getWidth();
			int layerHeight = layer.getBitmap().getHeight();
			c2.drawBitmap(layerBitmap, layer.getxLoc() - (layerWidth / 2),
					layer.getyLoc() - (layerHeight / 2), null);

			// draw highlight for selected image
			if (i == selectedLayer) {
				float left = layer.getxLoc() - (layerWidth / 2) - 1;
				float top = layer.getyLoc() - (layerHeight / 2) - 1;
				float right = left + layerWidth + 1;
				float bottom = top + layerHeight + 1;
				c2.drawRect(left, top, right, bottom, rectPaint);
			}
		}

		// draw all the save path of brush
		brush2.executeAll(c2, previewDoneHandler);

		// draw the preview path
		c2.drawPath(brush2.currentDrawingPath.path,
				brush2.currentDrawingPath.paint);

		// #################################################################

		// this canvas just display the bitmaps on the screen
		canvas.drawBitmap(mBitmap, 0, 0, null);

	}

	/**
	 * when user touches the screen, layer is selected if touched
	 * 
	 * @param eventX
	 * @param eventY
	 */
	public void handleActionDown(int eventX, int eventY) {
		// get selected layer by touching
		for (int i = layerArray.size() - 1; i >= 0; i--) {
			DrawingLayer layer = layerArray.get(i);
			int layerWidth = layer.getBitmap().getWidth();
			int layerHeight = layer.getBitmap().getHeight();

			if (eventX >= (layer.getxLoc() - layerWidth / 2)
					&& (eventX <= (layer.getxLoc() + layerWidth / 2))) {
				if (eventY >= (layer.getyLoc() - layerHeight / 2)
						&& (eventY <= (layer.getyLoc() + layerHeight / 2))) {
					setTouched(true);
					setSelectedLayer(i);
					selectedLayerX = layer.getxLoc();
					selectedLayerY = layer.getyLoc();
					Log.d("layer touch is", "layer " + i);
					break;
				} else {
					setTouched(false);
				}
			} else {
				setTouched(false);
			}
		}

	}

	/*
	 * Call resize
	 */
	public void resizeLayer(float initialDistance, float currentDistance) {
		layerArray.get(selectedLayer).resize(initialDistance, currentDistance);
	}
	
	public void setNewLayerSize(){
		layerArray.get(selectedLayer).setNewSize();
	}

	// add new image and set the thread to see it
	public void addImage(String imagePath) {
		Log.d("imagePath", imagePath);
		layerArray.add(new DrawingLayer(1, imagePath));
		Log.d("array size", " size is " + layerArray.size());

	}

	/**
	 * Add a text box with bubble background to canvas
	 * 
	 * @param int style String value
	 */
	public void addBubble(int style, String value) {
		EditText text = new EditText(mContext);
		text.setText(value);

		if (style == 0) {
			text.setBackgroundResource(R.drawable.square_bubble_left);
		} else if (style == 1) {
			text.setBackgroundResource(R.drawable.square_bubble_right);
		} else if (style == 2) {
			text.setBackgroundResource(R.drawable.round_bubble_left);
		} else if (style == 3) {
			text.setBackgroundResource(R.drawable.round_bubble_right);
		}
		text.setMaxWidth(300);

		text.setDrawingCacheEnabled(true);

		// this is the important code :)
		// Without it the view will have a dimension of 0,0 and the bitmap will
		// be null
		text.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
				MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
		text.layout(0, 0, text.getMeasuredWidth(), text.getMeasuredHeight());

		text.buildDrawingCache(true);
		Bitmap bitmap = Bitmap.createBitmap(text.getDrawingCache());
		text.setDrawingCacheEnabled(false); // clear drawing cache

		layerArray.add(new DrawingLayer(2, bitmap));
		setSelectedLayer(layerArray.size()-1);
	}

	/**
	 * Add a text with transparent background to canvas
	 * 
	 * @param int style String value
	 */
	public void addText(int style, String value) {
		EditText text = new EditText(mContext);
		text.setText(value);
		text.setBackgroundColor(Color.TRANSPARENT);

		if (style == 0) {
			text.setTextSize(11);
		} else if (style == 1) {
			text.setTextSize(16);
		} else if (style == 2) {
			text.setTextSize(22);
		}
		text.setMaxWidth(300);

		text.setDrawingCacheEnabled(true);

		// this is the important code :)
		// Without it the view will have a dimension of 0,0 and the bitmap will
		// be null
		text.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
				MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
		text.layout(0, 0, text.getMeasuredWidth(), text.getMeasuredHeight());

		text.buildDrawingCache(true);
		Bitmap bitmap = Bitmap.createBitmap(text.getDrawingCache());
		text.setDrawingCacheEnabled(false); // clear drawing cache

		layerArray.add(new DrawingLayer(2, bitmap));
		setSelectedLayer(layerArray.size()-1);
	}

	/**
	 * Delete selected layer
	 */
	public void deleteLayer() {
		if (layerArray.size() > 0) {
			layerArray.remove(selectedLayer);
		}
		isSelected = false;
	}

	/**
	 * Move selected layer to front
	 */
	public void moveToFront() {
		int size = layerArray.size();

		Log.d("selected array for swap", "size is " + size
				+ "   selectedLayer is " + selectedLayer);
		// swap if there are 2 or more items in arrays
		if (size > 1) {
			DrawingLayer toMove = layerArray.get(selectedLayer);
			layerArray.set(selectedLayer, layerArray.get(size - 1));
			layerArray.set(size - 1, toMove);
		}
	}

	/**
	 * move the layer by x amount and y amount in canvas
	 */
	public void moveLayerBy(int layer, int xAmount, int yAmount) {
		DrawingLayer dLayer = layerArray.get(layer);

		dLayer.setxLoc(selectedLayerX + xAmount);
		dLayer.setyLoc(selectedLayerY + yAmount);
	}

	/**
	 * 
	 * @param type
	 */
	public void addDivider(int type) {
		if (type == 0) {
			layerArray.add(new DrawingLayer(3, BitmapFactory.decodeResource(
					mRes, R.drawable.vertical_line)));
		} else if (type == 1){
			layerArray.add(new DrawingLayer(3, BitmapFactory.decodeResource(
					mRes, R.drawable.horizontal_line)));
		}
		
		setSelectedLayer(layerArray.size()-1);
	}

	// ------------- getters and setters -----------------------

	/*
	 * Set screen touch to true
	 */
	public void setTouched(boolean touched) {
		this.touched = touched;
	}

	/*
	 * Check if the user touches the screen
	 */
	public boolean isTouched() {
		return touched;
	}

	public void setSelectedLayer(int layer) {
		this.selectedLayer = layer;
		isSelected = true;
	}

	public int getSelectedLayer() {
		return selectedLayer;
	}

	public void setLayerXLoc(int layer, int x) {
		layerArray.get(layer).setxLoc(x);
	}

	public void setLayerYLoc(int layer, int y) {
		layerArray.get(layer).setyLoc(y);
	}

	// set image array after thread being resume
	public void setLayerArray(ArrayList<DrawingLayer> layerArray) {
		this.layerArray = layerArray;
	}

	/*
	 * getter of image array for data saving
	 */
	public ArrayList<DrawingLayer> getLayerArray() {
		return this.layerArray;
	}

	// set isSaved to save image
	public void setSave(boolean value) {
		isSaved = value;
	}

	/*
	 * set the type of brush
	 */
	public void setBrushArray(PaintBrush brush) {
		this.brush2 = brush;

	}

	/*
	 * get Bitmap for saving the image
	 */
	public Bitmap getBitmap() {
		return this.mBitmap;
	}

}